home *** CD-ROM | disk | FTP | other *** search
- /* WWTHETA: function calculates theta plot, finds ww features on it
- * and returns number of features found
- * usage: nThetaFeats = wwtheta (data, edge, wwPar,
- * nodesInLine, nNodesInLine, nodeList,
- * cycleFlag)
- * Note that a flag value of BORDERTHETA is put at the positions
- * at either end of the theta array to indicate the border
- * theta values which are not valid values.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "ww.h" /* wing-walk include file */
-
- extern long thetafeat (struct point *, struct edge, struct theta *,
- long, struct wwPar, short);
- int thetaarc (struct point *, struct edge, struct theta *, long);
- double thetacalc (struct point *, long, long, long, long);
- long thetasmth (struct theta *, long, long);
- double median (struct theta *, long);
- long wwends (struct point *, struct edge, struct theta *,
- long, long, long *, long *);
- long
- wwtheta (data, edge, wwPar, curveFlag)
- struct point *data; /* sequence of coordinates of lines */
- struct edge edge; /* lower/upper indices of segment in data */
- struct wwPar wwPar; /* wing-walk parameters */
- short curveFlag; /* =0 for curve fit by 2 lines; =1 for curve */
- {
- struct theta *theta; /* theta plot curv. and arc length array */
- double thetacalc ();
- long dataMid, /* middle pt on curve */
- iLower, iLow, /* data indices of lower W-segment */
- iHigh, iHigher, /* data indices of higher W-segment */
- nTheta, /* no. values in theta plot */
- iTheta, /* increment in theta array */
- flag, /* tests for beginning/end of data curve */
- nThetaFeats, /* no. of features found on theta plot */
- i;
-
- /* if line is too short to fit ww to, forget it */
- nTheta = edge.iHigh - edge.iLow + 1;
- if (nTheta <= wwPar.l)
- return (0);
-
- /* allocate space for theta plot */
- if ((theta = (struct theta *)
- calloc (nTheta, sizeof (struct theta))) == NULL) {
- printf ("CALLOC: not enough memory -- sorry");
- return (-1);
- }
-
- /* set theta to border flag, and calculate arc length along theta plot */
- for (i = 0; i < nTheta; i++)
- theta[i].theta = BORDERTHETA;
- thetaarc (data, edge, theta, nTheta);
-
- /* find start point where WMW fits within beginning of curve */
- for (dataMid = edge.iLow + 1, iTheta = 1;; dataMid++)
- if (wwends (data, edge, theta, dataMid, wwPar.l, &iLower, &iHigher)
- != -1)
- break;
-
- /* calculate theta plot */
- flag = 1;
- iTheta = dataMid - edge.iLow;
- while (flag >= 0) {
- wwends (data, edge, theta, dataMid, wwPar.m, &iLow, &iHigh);
- theta[iTheta].theta = thetacalc (data, iLower, iLow, iHigh, iHigher);
- dataMid++;
- iTheta++;
- flag = wwends (data, edge, theta, dataMid, wwPar.l,
- &iLower, &iHigher);
- }
-
- thetasmth (theta, nTheta, wwPar.m);
-
- /* determine WW features from theta plot */
-
- nThetaFeats = thetafeat (data, edge, theta, nTheta, wwPar, curveFlag);
-
- free (theta);
- return (nThetaFeats);
- }
-
-
- /* THETAARC: function computers arc length for each theta plot value
- * computed from the first data coordinate
- * usage: thetaarc (data, edge, theta, nTheta)
- */
-
- int
- thetaarc (data, edge, theta, nTheta)
- struct point *data; /* data coordinate array */
- struct edge edge; /* lower and upper <data> indices */
- struct theta *theta; /* theta plot with arc lengths */
- long nTheta; /* no. values in theta plot */
- {
- double incr; /* increment = 1 (horiz/vert), = 2 (diag) */
- long i, j;
- struct point diff; /* x and y differnces */
-
- theta[0].length = 0.0;
- for (i = 1, j = edge.iLow + 1; i < nTheta; i++, j++) {
- diff.x = data[j].x - data[j - 1].x;
- diff.y = data[j].y - data[j - 1].y;
- incr = (double) (ABS (diff.x) + ABS (diff.y));
- incr = (incr == 1.0) ? 1.0 : DIAG;
- theta[i].length = theta[i - 1].length + incr;
- }
- return (0);
- }
-
- /* THETACALC: function calculates theta angle between two line segments
- * usage: theta = thetacalc (data, iLower, iLow,
- * iHigh, iHigher)
- * double theta, thetacalc();
- */
-
- #include <math.h>
-
- #if defined(WIN32)
- #define PI 3.14159265358979
- #endif
- #define PID2 1.570796327
-
- double
- thetacalc (data, iLower, iLow, iHigh, iHigher)
- struct point *data; /* sequence of coordinates of lines */
- long iLower, iLow, /* data indices of lower W-segment */
- iHigh, iHigher; /* data indices of higher W-segment */
- {
- long deltaX, deltaY; /* x,y lengths of segments */
- double gammaLow, gammaHigh, /* angle of low and high segments */
- angle, /* theta angle calculation */
- k, /* constant */
- atan ();
-
- /* calculate angle of lower segment */
- deltaX = data[iLow].x - data[iLower].x;
- deltaY = data[iLow].y - data[iLower].y;
- if (deltaY >= 0 && deltaX >= 0)
- k = 0.0;
- else if (deltaY >= 0 && deltaX < 0)
- k = PI;
- else if (deltaY < 0 && deltaX >= 0)
- k = 0.0;
- else if (deltaY < 0 && deltaX < 0)
- k = PI;
- if (deltaX == 0)
- gammaLow = (deltaY >= 0) ? PID2 : -(PID2);
- else
- gammaLow = atan (((double) deltaY / (double) deltaX)) + k;
-
- /* calculate angle of higher segment */
- deltaX = data[iHigher].x - data[iHigh].x;
- deltaY = data[iHigher].y - data[iHigh].y;
- if (deltaY >= 0 && deltaX >= 0)
- k = 0.0;
- else if (deltaY >= 0 && deltaX < 0)
- k = PI;
- else if (deltaY < 0 && deltaX >= 0)
- k = 0.0;
- else if (deltaY < 0 && deltaX < 0)
- k = PI;
- if (deltaX == 0)
- gammaHigh = (deltaY >= 0) ? PID2 : -(PID2);
- else
- gammaHigh = atan (((double) deltaY / (double) deltaX)) + k;
-
- angle = gammaHigh - gammaLow;
- if (angle > PI)
- angle = angle - 2.0 * PI;
- else if (angle < -PI)
- angle = 2.0 * PI + angle;
-
- return (angle);
- }
-
-
- /* THETASMTH: function smooths theta plot with median filter
- * usage: thetasmth (theta, nTheta, wwParM)
- * Note that values of theta at beginning and end are
- * set to the first and last smoothed values respectively.
- */
-
- long
- thetasmth (theta, nTheta, wwParM)
- struct theta *theta; /* theta plot */
- long nTheta; /* no.values in theta plot */
- long wwParM; /* ww middle parameter */
- {
- double *thetaS; /* smoothed theta plot */
- long iStrt, iEnd, /* start and end output theta indices */
- halfWidth, /* half width of smooth filter -1 */
- i;
- double median ();
-
- /* allocate memory for smoothed theta output */
- if ((thetaS = (double *)
- calloc (nTheta, sizeof (*thetaS))) == NULL) {
- printf ("CALLOC: not enough memory -- sorry");
- return (-2);
- }
-
- /* smooth theta plot starting and ending with first correct theta values */
- halfWidth = wwParM / 2;
- for (iStrt = 0; iStrt < nTheta; iStrt++)
- if (theta[iStrt].theta != BORDERTHETA)
- break;
- iStrt = iStrt + halfWidth;
- for (iEnd = nTheta - 1; iEnd >= 0; --iEnd)
- if (theta[iEnd].theta != BORDERTHETA)
- break;
- iEnd = iEnd - halfWidth;
-
- for (i = iStrt; i <= iEnd; i++)
- thetaS[i] = median (&(theta[i - halfWidth]), wwParM);
-
- for (i = iStrt; i <= iEnd; i++)
- theta[i].theta = thetaS[i];
-
- return (0);
- }
-
-
- /* MEDIAN: function returns median value of window on theta plot
- * usage: m = median (&(theta[i].theta, width)
- * double m, median();
- */
-
- double
- median (theta, width)
- struct theta *theta; /* windowed portion of theta plot */
- long width; /* width of smoothing window */
- {
- int arrayle[MMAX], /* array of number of values that is less
- * * than or equal to the corresponding
- * * <value> */
- widthD2; /* window width divided by 2 */
-
- double value[MMAX]; /* value corresponding to less than or
- * * equal to array <arrayle> */
-
- register int sumle, /* running sum of less than or equals */
- sum, /* sum of numbers less than or equal to */
- i, j;
-
-
- /* initialize */
- for (i = 0; i < MMAX; i++)
- arrayle[i] = 0;
-
- /* construct less than or equal to array */
- for (i = 0; i < width; i++) {
- sumle = 0;
- for (j = 0; j < width; j++)
- if (theta[i].theta <= theta[j].theta)
- sumle++;
- arrayle[sumle]++;
- value[sumle] = theta[i].theta;
- }
-
- /* find median */
- widthD2 = width / 2;
- sum = 0;
- for (i = 1; i <= width; i++) {
- sum += arrayle[i];
- if (sum > widthD2)
- break;
- }
-
- return (value[i]);
- }
-
-
- /* WWENDS: function finds points on curve of equal arc length
- * above and below a given curve point
- * usage: returnFlag = wwends (data, edge, theta, iMidPt,
- * length, &iLow, &iHigh)
- * <returnFlag> = -1 if lower end of data reached; = -2
- * if higher end of data reached; = -3 if both reached;
- * = 0 if neither reached
- */
-
- #include <images.h> /* image format information */
-
- long
- wwends (data, edge, theta, iMidPt, length, iLow, iHigh)
- struct point *data; /* sequence of coordinates of curve */
- struct edge edge; /* strt and end indices of edges in data */
- struct theta *theta; /* theta plot curv. and arc length array */
- long iMidPt, /* middle point of arc */
- length, /* arc length from lower to higher point */
- *iLow, *iHigh; /* lower, and higher indices of data pts */
- {
- double halfLength, /* half length of line around point */
- arcLength, /* cumulative length of line */
- arcLengthB4; /* cumul. length before latest increment */
- long returnFlag, /* indicates either end of data reached */
- j;
-
- halfLength = (double) length / 2.0;
-
- /* find lower point */
- j = iMidPt;
- returnFlag = 0;
- arcLength = 0.0;
- do {
- --j;
- if (j < edge.iLow) {
- j = edge.iLow;
- returnFlag = -1;
- break;
- }
- arcLengthB4 = arcLength;
- arcLength = theta[iMidPt - edge.iLow].length
- - theta[j - edge.iLow].length;
- } while (arcLength < halfLength);
- *iLow = ((arcLength - halfLength) > (halfLength - arcLengthB4))
- ? (++j) : j;
-
- /* find higher point */
- j = iMidPt;
- arcLength = 0.0;
- do {
- j++;
- if (j > edge.iHigh) {
- j = edge.iHigh;
- returnFlag += -2;
- break;
- }
- arcLengthB4 = arcLength;
- arcLength = theta[j - edge.iLow].length
- - theta[iMidPt - edge.iLow].length;
- } while (arcLength < halfLength);
- *iHigh = ((arcLength - halfLength) > (halfLength - arcLengthB4))
- ? (--j) : j;
-
- return (returnFlag);
- }
-